package com.wimcorp.magic.abilities;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.wimcorp.magic.abilities.trigger.AbilityTrigger;
import com.wimcorp.magic.exception.CastException;

/**
 * example {target:'THIS',time_counter : 4}
 * 
 * target options : THIS
 * 
 * time_counter :
 * 
 * 
 * ability : DRAW_CARDS ability_trigger : on_counter_removed ability_config :
 * {target: 'SELF', amount:'1'}
 * 
 * ability : ADD_BEHAVIOUR ability_trigger : on_cast ability_config :
 * {target:'THIS',behaviors:['HASTE']}
 */
@Entity
@Table(name = "suspend", schema = "abilities")
public class Suspend extends Ability {

	@Transient
	private boolean exiled = false;
	@Transient
	private Set<Ability> timeCounterReducedObservers = new HashSet<>();
	@Transient
	private Set<Ability> unsuspendObservers = new HashSet<>();

	private int timeCounter;
	
	public Suspend() {
	}
	
	public Suspend(AbilityTrigger trigger) {
		super(trigger);
	}

	public Suspend(int timeCounter) {
		this.timeCounter = timeCounter;
	}
	
	public Suspend(Suspend ability) {
		super(ability);
		this.timeCounter = ability.getTimeCounter();
	}

	@Override
	protected void executeAbility() throws CastException {
		if (!exiled) {
			getPlayer().getSummoningPlaines().getExile().add(getCard());
			getPlayer().getBeginningPhase().registerUpkeepObserver(this);
			exiled = true;
		} else {
			timeCounter--;
			for (Ability ability : timeCounterReducedObservers) {
				getPlayer().cast(ability);
			}
			if (timeCounter == 0) {
				for (Ability ability : unsuspendObservers) {
					getPlayer().cast(ability);
				}
				getPlayer().castFromExileWithoutCost(getCard());
				getPlayer().getBeginningPhase().unRegisterUpkeepObserver(this);
			}
		}

	}

	public void registerTimeCounterReducedObserver(Ability ability) {
		timeCounterReducedObservers.add(ability);
	}

	public void unRegisterTimeCounterReducedObserver(Ability ability) {
		timeCounterReducedObservers.remove(ability);
	}

	public void registerUnsuspendObserversObserver(Ability ability) {
		unsuspendObservers.add(ability);
	}

	public void unRegisterUnsuspendObserversObserver(Ability ability) {
		unsuspendObservers.remove(ability);
	}

	public int getTimeCounter() {
		return timeCounter;
	}

	@Override
	public Suspend clone() {
		return new Suspend(this);
	}

	public void setTimeCounter(int timeCounter) {
		this.timeCounter = timeCounter;
	}
	
	

	
	
}
